package com.timmy.smarttest.utis;

import android.content.Context;
import android.text.TextUtils;
import android.util.Log;

import com.inuker.bluetooth.library.BluetoothClient;
import com.inuker.bluetooth.library.Code;
import com.inuker.bluetooth.library.Constants;
import com.inuker.bluetooth.library.connect.listener.BleConnectStatusListener;
import com.inuker.bluetooth.library.connect.listener.BluetoothStateListener;
import com.inuker.bluetooth.library.connect.options.BleConnectOptions;
import com.inuker.bluetooth.library.connect.response.BleConnectResponse;
import com.inuker.bluetooth.library.connect.response.BleNotifyResponse;
import com.inuker.bluetooth.library.connect.response.BleUnnotifyResponse;
import com.inuker.bluetooth.library.connect.response.BleWriteResponse;
import com.inuker.bluetooth.library.model.BleGattProfile;
import com.inuker.bluetooth.library.search.SearchRequest;
import com.inuker.bluetooth.library.search.SearchResult;
import com.inuker.bluetooth.library.search.response.SearchResponse;
import com.inuker.bluetooth.library.utils.ByteUtils;
import com.inuker.bluetooth.library.utils.UUIDUtils;
import com.timmy.smarttest.callback.BleCallbackImpl;

import java.util.UUID;

import static com.inuker.bluetooth.library.Constants.STATUS_CONNECTED;
import static com.inuker.bluetooth.library.Constants.STATUS_DISCONNECTED;

/**
 * 新版蓝牙工具类
 */

public class BleUtil {

    private static final String TAG = BleUtil.class.getSimpleName();
    private static volatile BleUtil instance = null;
    private static BluetoothClient mClient;

    // 连接的设备MAC地址
    private String connectDeviceMac = "";

    private BleUtil() {

    }

    public static BleUtil init(Context context) {
        if (instance == null) {
            synchronized (BleUtil.class) {
                if (instance == null) {
                    mClient = new BluetoothClient(context);
                    instance = new BleUtil();
                }
            }
        }
        return instance;
    }

    public static BleUtil getInstance() {
        return instance;
    }

    // 是否支持ble蓝牙
    public boolean isBleSupported() {
        return mClient.isBleSupported();
    }

    // 判断蓝牙是否打开
    public boolean isBluetoothOpened() {
        return mClient.isBluetoothOpened();
    }

    // 打开蓝牙
    public void openBle() {
        if (!isBluetoothOpened()) {
            mClient.openBluetooth();
        }
    }

    // 关闭蓝牙
    public void closeBle() {
        if (isBluetoothOpened()) {
            mClient.closeBluetooth();
        }
    }

    // 注册蓝牙打开关闭时间的监听
    public void registerBluetoothStateListener(BluetoothStateListener l) {
        mClient.registerBluetoothStateListener(l);
    }

    // 取消蓝牙打开监听
    public void unregisterBluetoothStateListener(BluetoothStateListener l) {
        mClient.unregisterBluetoothStateListener(l);
    }

    // 扫描蓝牙
    public void search() {
        SearchRequest request = new SearchRequest.Builder()
                .searchBluetoothLeDevice(2500, 2)   // 先扫BLE设备3次，每次3s
                .build();

        mClient.search(request, new SearchResponse() {
            @Override
            public void onSearchStarted() {
                if (mBleCallback != null) {
                    mBleCallback.onSearchStarted();
                }
            }

            @Override
            public void onDeviceFounded(SearchResult device) {
                if (mBleCallback != null) {
                    String name = device.getName();
                    if (!TextUtils.isEmpty(name) && name.contains("S002")) {
                        mBleCallback.onScan(device);
                    }
                }
            }

            @Override
            public void onSearchStopped() {
                if (mBleCallback != null) {
                    mBleCallback.onScanStop();
                }
            }

            @Override
            public void onSearchCanceled() {
                if (mBleCallback != null) {
                    mBleCallback.onScanStop();
                }
            }
        });
    }

    // 停止扫描
    public void stopSearch() {
        mClient.stopSearch();
    }

    // 蓝牙连接
    public void connect(String deviceMac) {
        this.connectDeviceMac = deviceMac;
        registerConnectStatusListener();
        BleConnectOptions options = new BleConnectOptions.Builder()
                .setConnectRetry(3)   // 连接如果失败重试3次
                .setConnectTimeout(30000)   // 连接超时30s
                .setServiceDiscoverRetry(3)  // 发现服务如果失败重试3次
                .setServiceDiscoverTimeout(20000)  // 发现服务超时20s
                .build();

        mClient.connect(deviceMac, options, new BleConnectResponse() {
            @Override
            public void onResponse(int code, BleGattProfile data) {
                if (mBleCallback == null) {
                    return;
                }
                if (code == Code.REQUEST_SUCCESS) {
                    mBleCallback.onBleConnected();
                } else if (code == Code.REQUEST_FAILED) {
                    mBleCallback.onBleDisconnected();
                }
            }
        });
    }

    // 断开连接
    public void disconnect() {
        if (!TextUtils.isEmpty(connectDeviceMac)) {
            mClient.disconnect(connectDeviceMac);
        }
    }

    // 写入数据
    public void write(byte[] bytes) {
        Log.v("蓝牙数据", "write: " + ByteUtils.byteToString(bytes));

        mClient.write(connectDeviceMac, getUUID(0001), getUUID(0002), bytes, new BleWriteResponse() {
            @Override
            public void onResponse(int code) {
                if (code == Code.REQUEST_SUCCESS) {

                } else if (code == Code.REQUEST_FAILED) {

                }
            }
        });
    }

    private BleCallbackImpl mBleCallback;

    public void registerNotifyListener(BleCallbackImpl callback) {
        this.mBleCallback = callback;
    }

    public void unRegisterNotifyListener() {
        mBleCallback = null;
    }

    // 开启通知
    public void openNotify() {
        mClient.notify(connectDeviceMac, getUUID(0001), getUUID(0003), new BleNotifyResponse() {
            @Override
            public void onNotify(UUID service, UUID character, byte[] value) {
                if (mBleCallback != null) {
                    mBleCallback.onNotify(value);
                }
            }

            @Override
            public void onResponse(int code) {
                if (code == Code.REQUEST_SUCCESS) {
                    Log.i(TAG, "开启通知成功");
                } else if (code == Code.REQUEST_FAILED) {
                    Log.i(TAG, "开启通知失败");

                }

            }
        });
    }

    // 关闭通知
    public void closeNotify() {
        mClient.unnotify(connectDeviceMac, getUUID(0001), getUUID(0003), new BleUnnotifyResponse() {
            @Override
            public void onResponse(int code) {
                if (code == Code.REQUEST_SUCCESS) {

                }
            }
        });
    }

    // 蓝牙设备连接状态
    public void registerConnectStatusListener() {
        mClient.registerConnectStatusListener(connectDeviceMac, mBleConnectStatusListener);
    }

    // 蓝牙设备主动断开
    public void unregisterConnectStatusListener() {
        mClient.unregisterConnectStatusListener(connectDeviceMac, mBleConnectStatusListener);
    }

    private final BleConnectStatusListener mBleConnectStatusListener = new BleConnectStatusListener() {

        @Override
        public void onConnectStatusChanged(String mac, int status) {
            if (status == STATUS_CONNECTED) {
                // 连接成功
                openNotify();
            } else if (status == STATUS_DISCONNECTED) {
                disconnectDevice();
            }
        }
    };


    public void refreshCache() {
        mClient.refreshCache(connectDeviceMac);
    }

    public boolean getBleState() {
        int status = mClient.getConnectStatus(connectDeviceMac);

        boolean state = false;
        switch (status) {
            case Constants.STATUS_DEVICE_DISCONNECTED:
                // 未连接
                state = false;
                break;
            case Constants.STATUS_DEVICE_CONNECTED:
                state = true;
                // 连接
                break;
        }
        return state;
    }

    private UUID getUUID(int uuid) {
        return UUIDUtils.makeUUID(uuid);
    }


    // 获取已连接设备的Mac地址
    public String getMac() {
        return connectDeviceMac;
    }

    // =================================== 发送数据 ===================================
    public void sendData(byte... bs) {
        if (!TextUtils.isEmpty(connectDeviceMac)) {
            int connectStatus = mClient.getConnectStatus(connectDeviceMac);
            if (connectStatus == Constants.STATUS_DEVICE_CONNECTED) {
                // 如果设备在连接
                write(DataUtils.getDataToSend(bs));
            }
        }
    }

    // 断开连接
    private void disconnectDevice() {
        unregisterConnectStatusListener();
        // 断开
        if (mBleCallback != null) {
            mBleCallback.onBleDisconnected();
        }
    }
}
